﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Linq;
using System.Windows.Forms;

namespace CustomControls
{
    [DesignerCategory(@"Code")]
    public sealed class DropDownButton : Button
    {

        private ContextMenuStrip _contextMenuStripFavorites;
        private LinearGradientBrush _backBrush;

        [Browsable(false), ReadOnly(true)]
        public override bool AutoSize
        { get { return base.AutoSize; } }

        //[Browsable(false), ReadOnly(true)]
        //public new AutoSizeMode AutoSizeMode
        //{ get { return base.AutoSizeMode; } }

        //[Browsable(false), ReadOnly(true)]
        //public new Image Image
        //{ get { return base.Image; } }

        [Browsable(false), ReadOnly(true)]
        public override string Text
        {
            get { return base.Text; }
        }

        [Browsable(false), ReadOnly(true)]
        public override ImageLayout BackgroundImageLayout
        {
            get
            { return base.BackgroundImageLayout; }
        }

        //[Browsable(false), ReadOnly(true)]
        //public new FlatStyle FlatStyle
        //{
        //    get { return base.FlatStyle; }
        //}

        [Browsable(false), ReadOnly(true)]
        public override ContentAlignment TextAlign
        {
            get
            {
                return base.TextAlign;
            }
        }

        //[Browsable(false), ReadOnly(true)]
        //public new TextImageRelation TextImageRelation
        //{
        //    get { return base.TextImageRelation; }
        //}

        //[Browsable(false), ReadOnly(true)]
        //public new bool UseMnemonic
        //{
        //    get { return false; }
        //}

        //[Browsable(false), ReadOnly(true)]
        //public new bool UseVisualStyleBackColor
        //{
        //    get { return false; }
        //}

        public DropDownButton()
        {
            base.AutoSize = false;

            BackgroundImageLayout = ImageLayout.None;
            FlatStyle = FlatStyle.Flat;
            FlatAppearance.BorderColor = Color.FromKnownColor(KnownColor.ControlDark);
            FlatAppearance.MouseDownBackColor = Color.FromKnownColor(KnownColor.Control);
            FlatAppearance.MouseOverBackColor = Color.FromKnownColor(KnownColor.Control);
            FlatAppearance.BorderSize = 0;
            TextAlign = ContentAlignment.MiddleLeft;
            TextImageRelation = TextImageRelation.TextBeforeImage;
            UseMnemonic = false;
            UseVisualStyleBackColor = false;
            _contextMenuStripFavorites = new ContextMenuStrip();
            _contextMenuStripFavorites.Closed += ContextMenuStripFavoritesClosed;
        }

        private void ContextMenuStripFavoritesClosed(object argSender, ToolStripDropDownClosedEventArgs argEvtArgs)
        {
            _backBrush = new LinearGradientBrush(ClientRectangle, Color.FromKnownColor(KnownColor.ControlLightLight), Color.FromKnownColor(KnownColor.Control), 90);
            Invalidate(true);
        }

        protected override void OnTextChanged(EventArgs argEvtArgs)
        {
            //Measure the string
            Graphics currentGraphic = CreateGraphics();
            int stringWidth;

            string thisText = Text;
            using (Font thisFont = new Font(Font, FontStyle.Regular))
            {
                SizeF thisSizeF = currentGraphic.MeasureString(thisText, thisFont);
                Size thisSize = thisSizeF.ToSize();
                stringWidth = thisSize.Width;
            }

            //Make the width larger than the string size
            Width = stringWidth + 15;
            base.OnTextChanged(argEvtArgs);
        }

        protected override void OnPaint(PaintEventArgs argPntEventArgs)
        {
            //Build brush
            if (_backBrush == null)
            {
                _backBrush = new LinearGradientBrush(ClientRectangle, Color.FromKnownColor(KnownColor.ControlLightLight), Color.FromKnownColor(KnownColor.Control), 90);
            }

            using (Pen localPen = new Pen(Color.FromKnownColor(KnownColor.ControlDark)))
            {
                //Draw box (round corners)
                argPntEventArgs.Graphics.FillRectangle(_backBrush, ClientRectangle);
                argPntEventArgs.Graphics.DrawRectangle(localPen, ClientRectangle.Top, ClientRectangle.Left, ClientRectangle.Width - 1, ClientRectangle.Height - 1);
            }

            string thisText = Text;

            using (Font thisFont = new Font(Font, FontStyle.Regular))
            {
                //Draw Text
                argPntEventArgs.Graphics.DrawString(thisText, thisFont, Brushes.Black, ClientRectangle.X, ClientRectangle.Y + 4);
            }

            Size startDownIn = new Size(1, 1);
            Size endDownIn = new Size(-1, 1);

            int pointX = ClientRectangle.X + ClientRectangle.Width - 13;
            int pointY = ClientRectangle.Top + 9;

            Point startPoint = new Point(pointX, pointY);

            pointX = ClientRectangle.X + ClientRectangle.Width - 7;
            //pointY = ClientRectangle.Top + 9;
            Point endPoint = new Point(pointX, pointY);

            argPntEventArgs.Graphics.DrawLine(Pens.Black, startPoint, endPoint);

            startPoint += startDownIn;
            endPoint += endDownIn;
            argPntEventArgs.Graphics.DrawLine(Pens.Black, startPoint, endPoint);

            startPoint += startDownIn;
            endPoint += endDownIn;
            argPntEventArgs.Graphics.DrawLine(Pens.Black, startPoint, endPoint);

            startPoint += startDownIn;
            argPntEventArgs.Graphics.DrawLine(Pens.Black, startPoint, endPoint);

        }

        protected override void OnMouseDown(MouseEventArgs argMEventArgs)
        {
            _backBrush = new LinearGradientBrush(ClientRectangle, Color.FromKnownColor(KnownColor.Control), Color.FromKnownColor(KnownColor.ControlLightLight), 90);
            base.OnMouseDown(argMEventArgs);
        }

        protected override void OnMouseUp(MouseEventArgs argMEventArgs)
        {
            _backBrush = new LinearGradientBrush(ClientRectangle, Color.FromKnownColor(KnownColor.ControlLightLight), Color.FromKnownColor(KnownColor.Control), 90);
            base.OnMouseUp(argMEventArgs);
        }

        protected override void OnClick(EventArgs argEvtArgs)
        {

            _backBrush = new LinearGradientBrush(ClientRectangle, Color.FromKnownColor(KnownColor.Control), Color.FromKnownColor(KnownColor.ControlLightLight), 90);

            _contextMenuStripFavorites.Tag = Tag;
            Point clientPoint = new Point(Parent.Location.X, Parent.Location.Y + Height - 2);

            _contextMenuStripFavorites.Show(PointToScreen(clientPoint));

            Invalidate(true);
            base.OnClick(argEvtArgs);
        }

        public void AddMenuItem(ToolStripMenuItem argNewItem)
        {
            argNewItem.Click += ItemClick;
            _contextMenuStripFavorites.Items.Add(argNewItem);
        }

        void ItemClick(object argSender, EventArgs argEvtArgs)
        {
            ToolStripDropDownItem clickedItem = (ToolStripDropDownItem)argSender;
            base.Text = @"[ " + clickedItem.Text + @" ]";
        }

        public void AddSeparator()
        {
            _contextMenuStripFavorites.Items.Add(new ToolStripSeparator());
        }

        public void ClearItems()
        {
            _contextMenuStripFavorites.Items.Clear();
        }

        public void SetFavorite(string argFavoritePath)
        {

            var favoriteItem =
                from ToolStripItem currentButton in _contextMenuStripFavorites.Items
                where ((string)currentButton.Tag) == argFavoritePath
                select currentButton;

            ToolStripMenuItem currentItem = (ToolStripMenuItem)favoriteItem.FirstOrDefault();

            if (currentItem == null)
            {
                if (argFavoritePath.StartsWith(@"\\"))
                {
                    try
                    {
                        DirectoryInfo rootDir = new DirectoryInfo(argFavoritePath).Root;
                        base.Text = @"[" + rootDir.Name + @" - Network Share ]";
                    }
                    catch (ArgumentException)
                    {
                        base.Text = @"[" + argFavoritePath + @" - Network Server ]";                        
                    }
                }
                else
                {
                    DriveInfo rootDrive = new DriveInfo(argFavoritePath);
                    base.Text = @"[" + rootDrive.Name + @" - " + rootDrive.VolumeLabel + @"]";
                }
            }
            else
            {
                base.Text = @"[" + currentItem.Text + @"]";
            }

        }
    }
}
